import React, { Component } from 'react';
import CountryCodeList from './countryCodeList/CountryCodeList';
import ClickItem from './ClickItem';
import fangg from './countryCodeList/fangg.json';
import './index.less';

const API = WPT.Util.handleApi({
    sendCode: '/v1.0/telephone/', // 发送验证码
    codeVerifyUrl: '/v1.0/telephone/to-update-tel-l', // 更新手机号
    telephoneVerifyUrl: '/v1.0/telephone/verify-tel-l', // 验证手机号是否可用
});

export default class VerifyTelephone extends Component {
    static defaultProps = {
        checkTypeObj: 'sms',
        checkType: ['sms', 'call'],
        telephoneVerifyUrl: API.telephoneVerifyUrl, // 验证电话号码
        sendCodeUrl: API.sendCode, // 发送 验证码
        codeVerifyUrl: API.codeVerifyUrl, // 验证 验证码
        callback: () => {}, // 验证完后的回调函数
        cancel: () => {}, // 取消回调
        verifyTelephone: '',
        type: 'bind', // bind 绑定手机号 verify验证手机号
        title: '请输入您的电话号码',
        tipsText: '完善您的联系方式',
        ajaxParam: {},
        stepInputCode: false, // 输入验证码
        sendCodeImme: false, // 立即发送验证码
    };

    constructor(props) {
        super(props);

        this.state = {
            verifyTelephoneTime: 60, // 60秒
            verifyTelephone: '', // 验证的电话号码
            secretCode: '', // 验证码
            confirmBtnTxt: '下一步',
            num: [
                { num: 1 },
                { num: 2, letter: 'ABC' },
                { num: 3, letter: 'DEF' },
                { num: 4, letter: 'GHI' },
                { num: 5, letter: 'JKL' },
                { num: 6, letter: 'MNO' },
                { num: 7, letter: 'PQRS' },
                { num: 8, letter: 'TUV' },
                { num: 9, letter: 'WXYZ' },
            ],
            sms: {
                // 短信验证的按钮
                keyDown: false, // 是否变灰
                txt: '短信验证', // 按钮文案
                isShow: true, // 按钮是否显示
            },
            call: {
                keyDown: false,
                txt: '点击进行语音验证',
                isShow: true,
            },
            ServiceTel: '0571-81110039',
            checkResult: '', // 验证完后提示信息
            country: 'CN', // 默认中国
            countryCode: '86', // 默认中国区号
            pattern: '^(86){0,1}1\\d{10}$', // 默认中国手机号校验
            stepGetPhone: true, // 获取手机号
            hasSendCode: false,
            showCountryCode: false, // 是否显示国家区号页面
            ...this.checkTelVerifyState(this.props),
        };
    }

    componentDidMount = () => {
        $(window).on('keydown', this.handleKeyInput);
    };

    componentWillUnmount() {
        WPT.Interval.clear('verifyTelephone');
        $(window).off('keydown', this.handleKeyInput);
    }

    hide = () => {
        this.props.cancel && this.props.cancel();
    };

    // 判断是否是国际号码，重置state
    checkTelVerifyState = params => {
        let newParams = { ...params };

        const { verifyTelephone } = newParams;
        // 国际号码，只能使用短信验证
        if (verifyTelephone && verifyTelephone.indexOf('-')) {
            const strTel = verifyTelephone.split('-');
            Object.keys(fangg).some(letter => fangg[letter].some(i => {
                if (i.code === strTel[0]) {
                    newParams = {
                        ...newParams,
                        country: i.abbreviation,
                        countryCode: i.code,
                        pattern: i.pattern,
                        verifyTelephone: strTel[1],
                        checkType: ['sms'],
                        checkTypeObj: 'sms',
                    };
                    return true;
                }
                return false;
            })
            );
        } else {
            // 国内电话使用传递进来的验证方式
            newParams.checkType = this.props.checkType;
            newParams.checkTypeObj = this.props.checkTypeObj;
        }

        // 获取验证码类型默认为[sms, call]的第一个元素，如果不在数组内，取第一个
        if (!newParams.checkType.includes(newParams.checkTypeObj)) {
            newParams.checkTypeObj = newParams.checkType[0]; // eslint-disable-line
        }

        return newParams;
    };

    // 处理键盘输入
    handleKeyInput = e => {
        if (e.keyCode == '8') {
            // Backspace  delete
            this.delete();
        }
        if (e.keyCode >= 48 && e.keyCode <= 57) {
            this.input(e.keyCode - 48);
        }
        if (e.keyCode >= 96 && e.keyCode <= 105) {
            this.input(e.keyCode - 96);
        }
    };

    format = num => {
        num = num.replace(/[\D]/g, ''); // 只能为数字

        if (!this.state.stepInputCode) {
            if (this.state.country === 'CN') {
                // 仅限中国手机号码
                num = num.slice(0, 11);
            }
        } else {
            num = num.substr(0, 4);
        }
        return num;
    };

    // 正则校验手机号码
    check = t => {
        const _emp = /^\s*|\s*$/g;
        const _reg = new RegExp(this.state.pattern);
        t = `${this.state.countryCode}${t.replace(_emp, '')}`; // 校验时拼上国家区号
        if (_reg.test(t)) {
            return 1;
        }
        return 0;
    };

    // 输入
    input = num => {
        if (this.state.stepInputCode) {
            this.state.secretCode = this.format(`${this.state.secretCode}${num}`);
        } else {
            this.state.verifyTelephone = this.format(`${this.state.verifyTelephone}${num}`);
        }
        this.forceUpdate();
    };

    // 发送短信或者呼叫电话号码  进行验证
    sendCode = sendCodetype => {
        const state = this.state;
        const obj = this.state[sendCodetype];
        if (this.state[sendCodetype] == undefined || this.state[sendCodetype].keyDown) {
            return;
        }
        WPT.Interval.clear('verifyTelephone');

        state.checkTypeObj = sendCodetype;

        state.verifyTelephoneTime = 60;
        state.verifyTelephoneTime -= 1;
        obj.keyDown = true;
        obj.txt = `${state.verifyTelephoneTime} 秒后可重新获取`;

        if (state.checkType.length == 2) {
            if (sendCodetype == 'sms') {
                state.call.isShow = false;
            } else if (sendCodetype == 'call') {
                state.sms.isShow = false;
            }
        }
        this.forceUpdate();

        WPT.Interval.append('verifyTelephone', () => {
            state.verifyTelephoneTime -= 1;
            state[state.checkTypeObj].txt = `${state.verifyTelephoneTime} 秒后可重新获取`;

            if (state.verifyTelephoneTime <= 0) {
                WPT.Interval.clear('verifyTelephone');
                state[state.checkTypeObj].txt = state.checkTypeObj == 'sms' ? '短信验证' : '语音验证';
                state[state.checkTypeObj].keyDown = false;
                if (state.checkType.length == 2) {
                    if (state.checkTypeObj == 'sms') {
                        state.call.isShow = true;
                    } else if (state.checkTypeObj == 'call') {
                        state.sms.isShow = true;
                    }
                }
            }

            this.forceUpdate();
        });

        WPT.getData(
            state.sendCodeUrl + sendCodetype,
            {
                tel: state.verifyTelephone,
                nationCode: state.countryCode,
                type: sendCodetype,
            },
            res => {
                this.setState({ tipsText: 'ArtificialValidation' });
                const code = res.errcode || res.code;
                const msg = res.errmsg || res.msg;

                if (code == 0) {
                    this.setState({
                        stepInputCode: true,
                        hasSendCode: true,
                        confirmBtnTxt: '确认',
                        secretCode: '',
                    });
                } else if (code == 1000) {
                    WPT.Modal.alert(`${msg}60秒后请重新再试`);
                } else {
                    WPT.Modal.alert(msg);
                }
            }
        );
    };

    // 提交
    submit = () => {
        // const self = this;
        const state = this.state;
        const telephone = state.verifyTelephone;
        state.checkResult = '';

        if (!state.stepInputCode) {
            if (!this.check(telephone)) {
                this.setState({ checkResult: '电话号码有误' });
                return;
            }
            WPT.Interval.clear('verifyTelephone'); // todo

            // 验证手机号，更改验证参数
            this.state = {
                ...this.state,
                ...this.checkTelVerifyState(this.state),
            };

            this.verifyTelIsUsed();
        } else {
            if (state.secretCode.length != 4) {
                this.setState({ checkResult: '验证码错误' });
                return;
            }
            this.updateTel();
        }
    };

    // 检查电话号码是否可用
    verifyTelIsUsed = () => {
        const state = this.state;
        const telephone = state.verifyTelephone;
        const nationCode = state.countryCode;
        WPT.postData(state.telephoneVerifyUrl, { ...state.ajaxParam, tel: telephone, nationCode }, res => {
            if (res.errcode == 0 || res.code == 0) {
                if (nationCode != '86') {
                    // 国际
                    state.checkTypeObj = 'sms';
                    state.checkType = ['sms'];
                }
                this.state.checkResult = '';
                this.state.stepInputCode = true;
                this.state.confirmBtnTxt = '确认';
                this.sendCode(state.checkTypeObj);
            } else {
                this.setState({ checkResult: res.errmsg || res.msg });
            }
        });
    };

    lastUpdateTelTime = 0;

    // 更新、绑定手机号
    updateTel = () => {
        // 一秒钟只能点击一次
        if (Date.now() - this.lastUpdateTelTime < 1000) {
            return;
        }
        this.lastUpdateTelTime = Date.now();

        const { state } = this;
        const telephone = state.verifyTelephone;
        const nationCode = state.countryCode;

        WPT.postData(
            state.codeVerifyUrl,
            {
                tel: state.verifyTelephone,
                code: state.secretCode,
                nationCode,
                checkTelephone: state.type == 'bind' ? 0 : 1, // type=bind更新绑定手机号，否则为语音验证手机号
            },
            res => {
                if (res.errcode == 0 || res.code == 0) {
                    if (res.data && res.data.errorList) {
                        this.setState({ errList: res.data.errorList });
                    } else {
                        // 电话验证通过
                        WPT.userinfo.hasTelephone = 88888888888;
                        WPT.userinfo.isSubscribe = 2;
                        this.closeModal();
                        state.callback(nationCode != '86' ? `${nationCode}-${telephone}` : telephone, res);
                    }
                } else {
                    this.setState({ checkResult: res.errmsg || res.msg });
                }
            }
        );
    };

    // 关闭弹窗
    closeModal = () => {
        this.props.close();
    };

    GOArtificialValidation = () => {
        this.setState({ tipsText: 'GOArtificialValidation' });
    };

    setShowCountrycodeList = (value = true) => {
        // 控制显示“选择国家”组件
        this.setState({ showCountryCode: value });
    };

    setCountryInfo = (country, countryCode, pattern) => {
        // 选择区号组件的回调函数
        this.setState({
            checkType: country !== 'CN' ? ['sms'] : this.props.checkType,
            country,
            countryCode,
            pattern,
        });
    };

    // 国内手机号格式化 // 从选择区号页面返回时调用
    formatVerifyTelephone = () => {};

    delete = () => {
        if (!this.state.stepInputCode) {
            this.state.verifyTelephone = this.format(
                this.state.verifyTelephone.substr(0, this.state.verifyTelephone.length - 1)
            );
        } else {
            this.state.secretCode = this.format(this.state.secretCode.substr(0, this.state.secretCode.length - 1));
        }
        this.setState({});
    };

    formatTel(tel = '') {
        return this.state.country === 'CN' ? tel.replace(/(\d{3})-?(\d{4})-?(\d{1,4}).*/, '$1-$2-$3') : tel;
    }

    getTitle() {
        // return '点击“语音验证” 验证码将以电话形式通知你';
        const state = this.state;
        const sendCodeStatus = `${state.hasSendCode ? '已' : '将'}发送至`;
        return (
            <div>
                <span className="darkRed">验证码</span>
                {state.checkTypeObj == 'sms' ? <span className="darkRed">{sendCodeStatus}</span> : sendCodeStatus}
                <span className="darkRed telephone">{state.verifyTelephone}</span>
            </div>
        );
    }

    render() {
        const state = this.state;
        if (state.isHide) {
            return null;
        }

        return (
            <div className="verifyTelephoneMainNew">
                {state.showCountryCode && (
                    <CountryCodeList
                        setCountryInfo={this.setCountryInfo}
                        setShowCountrycodeList={this.setShowCountrycodeList}
                        formatVerifyTelephone={this.formatVerifyTelephone}
                    />
                )}
                <div className={`verifyMain ${$.isEmptyObject(state.errList) ? '' : ' hide'}`}>
                    {state.stepInputCode ? (
                        <div className="secretCodeBox">
                            <div className="title">
                                {' '}
                                {this.getTitle()}
                                {' '}
                            </div>
                            {state.checkTypeObj == 'call' && (
                                <div className="callNotice">我们将在1分钟内给您来电，请及时接听</div>
                            )}
                            <div className="secretCode">
                                <div className="secretCodeInput">
                                    <span className={`hover ${!state.verifyTelephone ? '' : 'hasValue'}`}>
                                        {state.secretCode}
                                    </span>
                                </div>
                                <div className="checkBtnBanner">
                                    {state.checkType.indexOf('sms') > -1 && (
                                        <div
                                            className={`btn smsCheck ${state.sms.keyDown ? ' keyDown' : ''} ${
                                                state.sms.isShow ? '' : ' none'
                                            }`}
                                            {...WPT.onTouchEnd(this.sendCode.bind(this, 'sms'), 1)}
                                        >
                                            {state.sms.txt}
                                        </div>
                                    )}
                                    {state.checkType.indexOf('call') > -1 && (
                                        <div
                                            className={`btn callCheck ${state.call.keyDown ? ' keyDown' : ''} ${
                                                state.call.isShow ? '' : ' none'
                                            }`}
                                            {...WPT.onTouchEnd(this.sendCode.bind(this, 'call'), 1)}
                                        >
                                            {state.call.txt}
                                        </div>
                                    )}
                                </div>
                            </div>
                        </div>
                    ) : (
                        <div className="telephoneBox">
                            <div className="title" dangerouslySetInnerHTML={{ __html: state.title }} />
                            <div className="telephoneInput">
                                <div className="countryCodeButton" onClick={this.setShowCountrycodeList}>
                                    {`${state.country} +${state.countryCode}`}
                                </div>
                                <div className="separater" />
                                <span className={`hover ${!state.verifyTelephone ? '' : ' hasValue'}`}>
                                    {this.formatTel(state.verifyTelephone)}
                                </span>
                            </div>
                        </div>
                    )}

                    <div className="tips">
                        <div className="checkResult">{state.checkResult}</div>
                        <div className="tipText">
                            {state.tipsText == 'GOArtificialValidation' ? (
                                <div>
                                    请拨
                                    {' '}
                                    <a href={state.ServiceTel ? `tel:${state.ServiceTel}` : '#'}>{state.ServiceTel}</a>
                                    {' '}
                                    进行人工验证！
                                </div>
                            ) : state.tipsText == 'ArtificialValidation' ? (
                                <span {...WPT.onTouchEnd(this.GOArtificialValidation, 1)}>收不到验证码？</span>
                            ) : (
                                state.tipsText
                            )}
                        </div>
                    </div>

                    <div className="btnBanner">
                        <div className="confirmBtn" {...WPT.onTouchEnd(this.submit, 1)}>
                            {state.confirmBtnTxt}
                        </div>
                    </div>

                    <div
                        className="numkey"
                        onContextMenu={e => {
                            e.preventDefault();
                        }}
                    >
                        <ul>
                            {state.num.map(item => (
                                <ClickItem
                                    key={item.num}
                                    data-touch="touchEffect"
                                    className="num"
                                    // eslint-disable-next-line react/jsx-no-bind
                                    onClick={this.input.bind(this, item.num)}
                                >
                                    <div className="num">{item.num}</div>
                                    <div className="letter">{item.letter}</div>
                                </ClickItem>
                            ))}
                            <ClickItem data-touch="touchEffect" className="num othernum" onClick={this.hide}>
                                取消
                            </ClickItem>
                            <ClickItem
                                data-touch="touchEffect"
                                className="num"
                                style={{ lineHeight: '50px' }}
                                // eslint-disable-next-line react/jsx-no-bind
                                onClick={this.input.bind(this, 0)}
                            >
                                0
                            </ClickItem>
                            <ClickItem listenPress data-touch="touchEffect" className="delete" onClick={this.delete} />
                        </ul>
                    </div>
                </div>
                {
                    <div className={`errBox ${$.isEmptyObject(state.errList) ? ' hide' : ''}`}>
                        <div className="errTitle">
                            <span>当前账户已存在以下数据</span>
                            <br />
                            <span>{`暂时不能与 ${state.verifyTelephone} 绑定`}</span>
                        </div>
                        <div className="errContent">
                            {!$.isEmptyObject(state.errList)
                                && state.errList.map((errItem, i) => (
                                    <div key={i} className={`errItem ${errItem.icon}`}>
                                        <div className="itemTitle">
                                            <i className={`wptFM icon-fm-${errItem.icon}`} />
                                            {errItem.name}
                                        </div>
                                        <div className="itemContent">{errItem.value}</div>
                                    </div>
                                ))}
                        </div>
                        <div className="errButton" {...WPT.onTouchEnd(this.closeModal, 0)}>
                            <button>我知道了</button>
                        </div>
                    </div>
                }
            </div>
        );
    }
}
